package gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.JList;
import javax.swing.JPopupMenu;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;

import logic.Suggestor;

//@author A0100965J
public class SuggestionPanel {
	private JList list;
	private JPopupMenu popupMenu;
	private String subWord;
	private int insertionPosition;
	private JTextField cmdLine;

	public SuggestionPanel(KeyMonitor keyMonitor, String subWord, Point location, boolean isCommandWord) {
		this.cmdLine = keyMonitor.getCommand();
		this.insertionPosition = cmdLine.getCaretPosition();
		this.subWord = subWord;
		popupMenu = new JPopupMenu();
		popupMenu.removeAll();
		popupMenu.setOpaque(false);
		popupMenu.setBorder(null);
		list = createSuggestionList(subWord, isCommandWord);
		if (list != null) {
			// Show suggestion popup
			popupMenu.add(list, BorderLayout.CENTER);
			popupMenu.show(cmdLine, location.x, cmdLine.getBaseline(20, 20) + location.y);
		}
	}

	/**
	 * Hide the suggestion popup
	 */
	public void hide() {
		popupMenu.setVisible(false);
	}

	/**
	 * Create the list of suggested words according to the subWord
	 * 
	 * @param subWord
	 * @return the list of suggested words
	 */
	private JList createSuggestionList(String subWord, boolean isCommandWord) {
		Vector<String> data = new Vector<String>();

		ArrayList<String> suggestedList;
		if (isCommandWord) {
			suggestedList = Suggestor.getInstance().suggestCommandWord(subWord);
		} else {
			suggestedList = Suggestor.getInstance().suggest(subWord);
		}

		if (suggestedList != null) {
			data = new Vector<String>(suggestedList);
		}

		JList list = null;
		if (data != null && data.size() > 0) {
			list = new JList(data);
			list.setOpaque(false);
			list.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 0));
			list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
			list.setSelectedIndex(0);
		}
		return list;
	}

	/**
	 * Insert the selected suggestion into the command line at the cursor
	 * 
	 * @return true if the insertion the list of suggestion is not null
	 */
	public boolean insertSelection() {
		String selectedSuggestion = null;
		if (list != null) {
			Object selectedValue = list.getSelectedValue();
			if (selectedValue != null) {
				selectedSuggestion = ((String) list.getSelectedValue()).substring(subWord.length());
			}
			int cursor = cmdLine.getCaretPosition();
			StringBuilder cmd = new StringBuilder(cmdLine.getText());
			cmd.insert(insertionPosition, selectedSuggestion);
			cmdLine.setText(cmd.toString());
			cmdLine.setCaretPosition(cursor + selectedSuggestion.length());
			this.hide();
			return true;
		}

		return false;
	}

	/**
	 * Move up by one row in the suggestion list
	 */
	public void moveUp() {
		int index = Math.min(list.getSelectedIndex() - 1, 0);
		selectIndex(index);
	}

	/**
	 * Move down by one row in the suggestion list
	 */
	public void moveDown() {
		int index = Math.min(list.getSelectedIndex() + 1, list.getModel().getSize() - 1);
		selectIndex(index);
	}

	/**
	 * Get the index of the selected word in the suggestion list
	 * 
	 * @param index
	 */
	private void selectIndex(int index) {
		int cursor = cmdLine.getCaretPosition();
		list.setSelectedIndex(index);
		cmdLine.setCaretPosition(cursor);
	}

	/**
	 * Check if the suggestion list is empty
	 * 
	 * @return true if the list is empty
	 */
	public boolean isEmpty() {
		return (list == null);
	}
}
